﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;
using PepsiCo.Business;
using System.Configuration;

namespace PepsiCo.UI
{
    public class BasePage : System.Web.UI.Page
    {
        #region Properties
        private PepsiCoDBDataContext db = new PepsiCoDBDataContext(LocalSetting.ConnectionString);
        public PepsiCoDBDataContext DB
        {
            get { return db; }
        }
        public pepsi_User CurUser
        {
            get
            {
                if (Session[_SESSION.USER_NAME] == null) return null;
                return (pepsi_User)Session[_SESSION.USER_NAME];
            }
            set
            {
                if (Session[_SESSION.USER_NAME] == null)
                    Session.Add(_SESSION.USER_NAME, value);
                else Session[_SESSION.USER_NAME] = value;
            }
        }
        public string AccessDeniedURL
        {
            get { return ConfigurationManager.AppSettings["AccessDeniedURL"]; }
        }
        public string DefaultURL
        {
            get { return ConfigurationManager.AppSettings["DefaultURL"]; }
        }
        public string LoginURL
        {
            get { return ConfigurationManager.AppSettings["LoginURL"]; }
        }
        public string ReturnURL
        {
            get
            {
                string returnURL = (string)Session[_SESSION.RETURN_URL];
                if (returnURL == null || returnURL == AccessDeniedURL || returnURL == LoginURL) return DefaultURL;
                return returnURL;
            }
            set
            {
                if (Session[_SESSION.RETURN_URL] == null)
                    Session.Add(_SESSION.RETURN_URL, value);
                else
                    Session[_SESSION.RETURN_URL] = value;
            }
        }
        private bool isRefresh;
        public bool IsRefresh
        {
            get { return isRefresh; }
        }
        public int PageSize
        {
            get
            {
                if (Session[_SESSION.PageSize] == null) return 50;
                return (int)Session[_SESSION.PageSize];
            }
            set
            {
                if (Session[_SESSION.PageSize] == null)
                    Session.Add(_SESSION.PageSize, value);
                else
                    Session[_SESSION.PageSize] = value;
            }

        }
        #endregion
       
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (RequiredLogin())
            {
                if (Session.IsNewSession)
                    Session.Timeout = 60;
                ReturnURL = Request.RawUrl;
                RedirectToPage(LoginURL);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            //Check IsRefresh
            if (!IsPostBack)
            {
                isRefresh = false;
                Session[_SESSION.PostID] = (int)0;
                ViewState[_SESSION.PostID] = (int)0;
            }
            else
            {
                if ((int)Session[_SESSION.PostID] == (int)ViewState[_SESSION.PostID])
                {
                    Session[_SESSION.PostID] = (int)Session[_SESSION.PostID] + 1;
                    ViewState[_SESSION.PostID] = (int)Session[_SESSION.PostID];
                    isRefresh = false;
                }
                else
                {
                    ViewState[_SESSION.PostID] = (int)Session[_SESSION.PostID];
                    isRefresh = true;
                }
            }
            base.OnLoad(e);
        }
       
        protected virtual bool RequiredLogin()
        {
            if (Session[_SESSION.USER_NAME] == null)
                return true;
            return false;
        }
        
        #region Utils
        /// <summary>
        /// Điều hướng trang
        /// </summary>
        /// <param name="urlPage">Địa chỉ điều hướng</param>
        protected void RedirectToPage(string urlPage)
        {
            Response.Redirect(urlPage);
        }

        protected string GetQueryString(string parameter)
        {
            if (Request.QueryString[parameter] == null) return string.Empty;
            return (string)Request.QueryString[parameter];
        }

        public string GetIdentString(int ident)
        {
            string retValue = string.Empty;
            for (int i = 0; i < ident; i++) retValue += "--";
            return retValue;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public void ShowMessageBox(string message)
        {
            string script = string.Format(@"alert(""{0}"");", message.Replace("\"", "'").Replace(Environment.NewLine, "\\n"));
            System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "", script, true);
        }

        /// <summary>
        /// Đăng ký script cho trang sau khi postback
        /// </summary>
        /// <param name="script"></param>
        public void RegisterStartUpScript(string script)
        {
            System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(), "", script, true);
        }

        /// <summary>
        /// Đăng ký script cho control nằm trong UpdatePanel
        /// </summary>
        /// <param name="script"></param>
        public void RegisterClientScriptBlock(string script)
        {
            System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "", script, true);
        }
        #endregion
        
        #region Permission
        protected virtual bool AllowSendMessage()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                                       (p.pepsi_Role.RoleName == Role.SendMessage || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug=> ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg=>
                        rg.pepsi_Role.RoleName == Role.SendMessage || rg.pepsi_Role.RoleName == Role.Admin)))

                return true;
            return false;
        }

        protected virtual bool AllowCreateUser()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.CreateUser || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug=> ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg=>
                        rg.pepsi_Role.RoleName == Role.CreateUser || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowDeleteUser()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.DeleteUser || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.DeleteUser || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowCreateUnit()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.CreateUnit || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.CreateUnit || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowDeleteUnit()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.DeleteUnit || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.DeleteUnit || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowCreateSale()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.CreateSale || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.CreateSale || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowDeleteSale()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.DeleteSale || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.DeleteSale || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowGrantPrivileges()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.GrantPrivileges || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.GrantPrivileges || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowEditUser()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.EditUser || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.EditUser || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowEditUnit()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.EditUnit || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.EditUnit || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowEditSale()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.EditSale || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.EditSale || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowEditFunction()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.EditFunction || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.EditFunction || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowCreateGroup()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.CreateGroup || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.CreateGroup || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowDeleteGroup()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.DeleteGroup || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.DeleteGroup || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowEditGroup()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.EditGroup || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.EditGroup || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool AllowViewReport()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID &&
                           (p.pepsi_Role.RoleName == Role.ViewReport || p.pepsi_Role.RoleName == Role.Admin))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.ViewReport || rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool IsAdmin()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID
                            && p.pepsi_Role.RoleName == Role.Admin)
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.Admin)))
                return true;
            return false;
        }

        protected virtual bool IsRootAdmin()
        {
            if (CurUser == null)
                return false;
            if (DB.pepsi_User_Roles.Any(p => p.UserID == CurUser.UserID
                            && p.pepsi_Role.RoleName == Role.Admin
                            && CurUser.Name.Equals(Constants.AdminRootAccount, StringComparison.CurrentCultureIgnoreCase))
                ||
                DB.pepsi_User_Groups.Any(ug => ug.UserID == CurUser.UserID &&
                    ug.pepsi_Group.pepsi_Role_Groups.Any(rg =>
                        rg.pepsi_Role.RoleName == Role.Admin && CurUser.Name.Equals(Constants.AdminRootAccount, StringComparison.CurrentCultureIgnoreCase))))
                return true;
            return false;
        }
        #endregion
    }


    public class _SESSION
    {
        public const string USER_NAME = "USERNAME";
        public const string RETURN_URL = "ReturnURL";
        public const string PostID = "PostID";
        public const string PageSize = "PageSize";
        public const string ActiveLink = "ActiveLink";
    }

    public class _COOKIES
    {
        public const string LOGIN = "LOGIN";
        public const string USERNAME = "USERNAME";
        public const string PASSWORD = "PASSWORD";
    }


    public class Constants
    {
        public const string AdminRootAccount = "Admin";
    }
}